LL_OPAMP_Init and LL_OPAMP_DeInit APIs migration

The LL initialization and de-initialization functions previously available in the stm32tnxx_ll_opamp.c files within HAL1 are no longer present in HAL2. In HAL2, all LL C files ( stm32tnxx_ll_opamp.c) have been removed, leaving only the LL header files ( stm32tnxx_ll_opamp.h) that contain static inline functions.

If users need to initialize or de-initialize OPAMP using the LL layer, they have two methods:

  • Utilize STM32CubeMX2 Code Generation: Rely on STM32CubeMX2 to generate code with the LL layer for OPAMP initialization and de-initialization.

  • Replace manually the initialization and de-initialization functionsReplace the LL_OPAMP_Init and LL_OPAMP_DeInit functions

    manually with equivalent sequences using the static inline functions provided in the stm32tnxx_ll_opamp.h file, tailored to their specific configuration and requirements.

This approach ensures that the initialization and de-initialization sequences are precisely addressing the given use case based on the LL static inline functions provided in the stm32tnxx_ll_opamp.h header file. The sequences offer improved footprint optimization compared to the previous LL initialization functions found in stm32tnxx_ll_opamp.c.

Related concept: Remove stm32tnxx_ll_ppp.c files

Method 1: Utilize STM32CubeMX2 Code Generation

LL OPAMP configuration panel

Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.

Project configuration panel

LL OPAMP main features configuration

Configure the OPAMP main features.

OPAMP main feature configuration

LL OPAMP advanced features configuration

Configure the advanced OPAMP features.

OPAMP advanced feature configuration

LL OPAMP GPIO configuration

Configure GPIO pins.

OPAMP GPIO configuration

Generated OPAMP initialization sequence

The OPAMP initialization and de-initialization sequences are generated in the mx_opamp1_init and mx_opamp1_deinit functions in mx_opamp1.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

STM32CubeMX2 Generated : OPAMP initialization sequence

Topic

Code Snippet HAL1

Code Snippet HAL2

Init and config sequence function

static void MX_OPAMP1_Init(void)
{
   LL_OPAMP_InitTypeDef OPAMP_InitStruct = {0};

   LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

   /* Peripheral clock enable */
   LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_OPAMP);

   LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
   /**OPAMP1 GPIO Configuration
   PA1   ------> OPAMP1_VINP
   PA2   ------> OPAMP1_VINM
   PA6   ------> OPAMP1_VOUT
   */
   GPIO_InitStruct.Pin = LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_6;
   GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
   GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
   LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

   OPAMP_InitStruct.PowerMode = LL_OPAMP_POWERMODE_NORMALPOWER_NORMALSPEED;
   OPAMP_InitStruct.FunctionalMode = LL_OPAMP_MODE_STANDALONE;
   OPAMP_InitStruct.InputNonInverting = LL_OPAMP_INPUT_NONINVERT_IO0;
   OPAMP_InitStruct.InputInverting = LL_OPAMP_INPUT_INVERT_IO0;
   LL_OPAMP_Init(OPAMP1, &OPAMP_InitStruct);
   LL_OPAMP_SetCommonPowerRange(__LL_OPAMP_COMMON_INSTANCE(OPAMP1), LL_OPAMP_POWERSUPPLY_RANGE_HIGH);
   LL_OPAMP_SetTrimmingMode(OPAMP1, LL_OPAMP_TRIMMING_FACTORY);

}
OPAMP_TypeDef *mx_opamp1_init(void){
   LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_OPAMP1);

   /****************************************************************************/
   /* Configuration of basic features (mandatory)                              */
   /****************************************************************************/

   LL_OPAMP_SetConfig(OPAMP1, (LL_OPAMP_MODE_FUNCTIONAL
                                 | LL_OPAMP_SPEED_MODE_NORMAL
                                 | LL_OPAMP_MODE_STANDALONE
                                 | LL_OPAMP_INPUT_NONINVERT_IO0
                                 | LL_OPAMP_INPUT_INVERT_IO0
                                 | LL_OPAMP_OUTPUT_CONNECT_EXTERNAL)
                     );

   /* GPIO Clocks activation */
   LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);

   /**
      OPAMP1 GPIO Configuration

      [GPIO Pin] ------> [Signal Name]

         PA1     ------>   OPAMP1_VINP0
         PA6     ------>   OPAMP1_VOUT
         PA2     ------>   OPAMP1_VINM0
      **/

   /* Activate the Pull-up, Pull-down resistor, or No pull for the current IO */
   LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_1, LL_GPIO_PULL_NO);
   LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_6, LL_GPIO_PULL_NO);
   LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_2, LL_GPIO_PULL_NO);

   /* Configure IO direction mode (Input, Output, Alternate or Analog) */
   LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_1, LL_GPIO_MODE_ANALOG);
   LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_6, LL_GPIO_MODE_ANALOG);
   LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_2, LL_GPIO_MODE_ANALOG);

   return OPAMP1;
}

Deinit sequence function

void MX_OPAMP_DeInit(void)
{
  LL_OPAMP_DeInit(OPAMP1);
}
void mx_opamp1_deinit(void)
{
   LL_OPAMP_Disable(OPAMP1);

   LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_OPAMP1);
   LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_OPAMP1);

   LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_OPAMP1);

   /* ### GPIO deinitialization of OPAMP1: OPAMP1_VINP0,OPAMP1_VOUT,OPAMP1_VINM0 ########################### */

   /* Configure IO in Analog Mode */
   LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_1, LL_GPIO_MODE_ANALOG);
   LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_6, LL_GPIO_MODE_ANALOG);
   LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_2, LL_GPIO_MODE_ANALOG);

   /* Configure the default Alternate Function in current IO */
   LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_1, LL_GPIO_AF_0);
   LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_6, LL_GPIO_AF_0);
   LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_2, LL_GPIO_AF_0);

   /* Configure the default value for IO Speed */
   LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_1, LL_GPIO_SPEED_FREQ_LOW);
   LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_6, LL_GPIO_SPEED_FREQ_LOW);
   LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_2, LL_GPIO_SPEED_FREQ_LOW);

   /* Configure the default value IO Output Type */
   LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_1 | LL_GPIO_PIN_6 | LL_GPIO_PIN_2, LL_GPIO_OUTPUT_PUSHPULL);

   /* Deactivate the Pull-up and Pull-down resistor for the current IO */
   LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_1, LL_GPIO_PULL_NO);
   LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_6, LL_GPIO_PULL_NO);
   LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_2, LL_GPIO_PULL_NO);

   /* Reset the IO output state */
   LL_GPIO_WriteOutputPin(GPIOA, LL_GPIO_PIN_1 | LL_GPIO_PIN_6 | LL_GPIO_PIN_2, LL_GPIO_PIN_RESET);
}

Method 2: Replace manually the initialization and de-initialization functions

LL_OPAMP_Init() API migration

According to the use-case, implement the precise sequence call based on the LL static inline functions provided in the stm32tnxx_ll_opamp.h header file.

OPAMP Mode Comparison between HAL1 and HAL2

HAL1

HAL2

OPAMP MODE PGA

LL_OPAMP_InitTypeDef OPAMP_initStruct;
/* Set OPAMP_InitStruct fields to default values */
OPAMP_InitStruct->PowerMode         = LL_OPAMP_POWERMODE_NORMALPOWER_NORMALSPEED;
OPAMP_InitStruct->FunctionalMode    = LL_OPAMP_MODE_PGA;
OPAMP_InitStruct->InputNonInverting = LL_OPAMP_INPUT_NONINVERT_IO0;
OPAMP_InitStruct->InputInverting    = LL_OPAMP_INPUT_INVERT_CONNECT_NO;

LL_OPAMP_Init(OPAMP1, OPAMP_initStruct);

OPAMP MODE PGA

LL_OPAMP_SetLowPowerMode(OPAMP1, LL_OPAMP_POWER_MODE_NORMAL);
LL_OPAMP_SetSpeedMode(OPAMP1, LL_OPAMP_SPEED_MODE_NORMAL).
LL_OPAMP_SetConfigurationMode(OPAMP1, LL_OPAMP_MODE_PGA;
LL_OPAMP_SetMode(OPAMP1, LL_OPAMP_MODE_FUNCTIONAL);
LL_OPAMP_SetInputInverting(OPAMP1, LL_OPAMP_INPUT_INVERT_CONNECT_NO)
LL_OPAMP_SetInputNonInverting(OPAMP1, LL_OPAMP_INPUT_NONINVERT_IO0)

OPAMP MODE FOLLOWER

LL_OPAMP_InitTypeDef OPAMP_initStruct;
/* use the default values initialization */
LL_OPAMP_StructInit(OPAMP_initStruct);
LL_OPAMP_Init(OPAMP1, OPAMP_initStruct);
/*Or*/
/* Set OPAMP_InitStruct fields to default values */
OPAMP_InitStruct->PowerMode         = LL_OPAMP_POWERMODE_NORMALPOWER_NORMALSPEED;
OPAMP_InitStruct->FunctionalMode    = LL_OPAMP_MODE_FOLLOWER;
OPAMP_InitStruct->InputNonInverting = LL_OPAMP_INPUT_NONINVERT_IO0;
OPAMP_InitStruct->InputInverting    = LL_OPAMP_INPUT_INVERT_CONNECT_NO;

LL_OPAMP_Init(OPAMP1, OPAMP_initStruct);

OPAMP MODE FOLLOWER

LL_OPAMP_SetLowPowerMode(OPAMP1, LL_OPAMP_POWER_MODE_NORMAL);
LL_OPAMP_SetSpeedMode(OPAMP1, LL_OPAMP_SPEED_MODE_NORMAL).
LL_OPAMP_SetConfigurationMode(OPAMP1, LL_OPAMP_MODE_FOLLOWER;
LL_OPAMP_SetMode(OPAMP1, LL_OPAMP_MODE_FUNCTIONAL);
LL_OPAMP_SetInputInverting(OPAMP1, LL_OPAMP_INPUT_INVERT_CONNECT_NO)
LL_OPAMP_SetInputNonInverting(OPAMP1, LL_OPAMP_INPUT_NONINVERT_IO0)

OPAMP MODE STANDALONE

LL_OPAMP_InitTypeDef OPAMP_initStruct;
/* Set OPAMP_InitStruct fields*/
OPAMP_initStruct->PowerMode         = LL_OPAMP_POWERMODE_NORMALPOWER_NORMALSPEED;
OPAMP_initStruct->FunctionalMode    = LL_OPAMP_MODE_STANDALONE;
OPAMP_initStruct->InputNonInverting = LL_OPAMP_INPUT_NONINVERT_IO0;
OPAMP_initStruct->InputInverting    = LL_OPAMP_INPUT_INVERT_CONNECT_NO;

LL_OPAMP_Init(OPAMP1, OPAMP_initStruct);

OPAMP MODE STANDALONE

LL_OPAMP_SetLowPowerMode(OPAMP1, LL_OPAMP_POWER_MODE_NORMAL);
LL_OPAMP_SetSpeedMode(OPAMP1, LL_OPAMP_SPEED_MODE_NORMAL).
LL_OPAMP_SetConfigurationMode(OPAMP1, LL_OPAMP_MODE_STANDALONE;
LL_OPAMP_SetMode(OPAMP1, LL_OPAMP_MODE_FUNCTIONAL);
LL_OPAMP_SetInputInverting(OPAMP1, LL_OPAMP_INPUT_INVERT_CONNECT_NO)
LL_OPAMP_SetInputNonInverting(OPAMP1, LL_OPAMP_INPUT_NONINVERT_IO0)

LL_OPAMP_DeInit() API migration

According to the used OPAMP instance, Implement the precise calls to LL_OPAMP_WRITE_REG().

Example: The application is using OPAMP1

Comparison of HAL1 and HAL2

HAL1

HAL2

LL_OPAMP_DeInit(OPAMP1);
LL_OPAMP_WRITE_REG(OPAMP1, CSR, 0x00000000UL);